<template>
  <div id="app">
    <div v-show="false" class="author">作者QQ：2282017407@qq.com</div>
    <div class="level">第{{ number2str }}关</div>
    <div class="box">
      <div @click="slectedCard(item,index,$event)" v-for="(item,index) in allCards" :key="index"
           :style="{left:item.left,top:item.top}" class="card">
        <img :src="`./icon/${item.icon}.png`" :alt="item.id">
        <div class="bot"></div>
      </div>
    </div>
    <!--选择的卡片-->
    <div class="bottom">
      <div v-for="(item,index) in slectedCardList" :key="index" class="card">
        <img :src="`./icon/${item.icon}.png`" :alt="index">
      </div>
    </div>
    <!--重新开始-->
    <div class="btn">
      <el-button @click="initData" type="primary">重新开始游戏</el-button>
      <el-button v-if="level > 1" @click="backLevel" type="primary">返回第一关</el-button>
      <el-button v-if="historySlectedCard.length > 0" @click="backHistory" type="primary">撤回</el-button>
    </div>
    <!--作者-->
    <div class="author version">version:1.0</div>
  </div>
</template>

<script>
//icon生成几个
const initIconNumber = 9;
export default {
  data(){
    return{
      //第几关
      level:1,
      //icon生成几个
      iconNumber:initIconNumber,
      //保存所有棋子
      allCards:[
        // {id:1,order:1,icon:'',left:'0',top:'0'},
        // {id:2,order:1,icon:'',left:'50px',top:'0'},
      ],
      //卡片定位数组
      cardPositionList:[],
      //选择的卡片
      slectedCardList:[],
      //记录选择的卡片，用于撤回
      historySlectedCard:[],
      //当前选择的卡片
      currentSlectedCard:{},
      //icon保存
      iconList:[
        {order:0,icon:1,bg:'#c08020'},
        {order:1,icon:2,bg:'#48a794'},
        {order:2,icon:3,bg:'#4869a7'},
        {order:3,icon:4,bg:'#d4624f'},
        {order:4,icon:5,bg:'#452b26'},
        {order:5,icon:6,bg:'#ffffff'},
        {order:6,icon:7,bg:'#be4eca'},
        {order:7,icon:8,bg:'#b7bc36'},
        {order:8,icon:9,bg:'#424c88'},
        {order:9,icon:10,bg:'#f70911'},
      ]
    }
  },
  created() {
    this.initData()
  },
  computed:{
    number2str(){
      return ['一','二','三','四','五','六','七','八','九','十'][this.level-1]
    }
  },
  methods:{
    //撤回
    backHistory(){
      //获取最后一个选中的
      let lastSlect = this.historySlectedCard[this.historySlectedCard.length-1];
      if (this.historySlectedCard.length < 1){
        alert("没有可以撤回的卡片！！！");
        return;
      }
      //消除记录里面的
      this.historySlectedCard = this.historySlectedCard.filter(item=>{
        return item.id !== lastSlect.id;
      })
      //消除选择里面的
      this.slectedCardList = this.slectedCardList.filter(item=>{
        return item.id !== lastSlect.id;
      })
      //重新给allCards添加撤回的卡片
      console.log(lastSlect)
      this.allCards.push(lastSlect);
    },
    //返回上一关并且重新开始
    backLevel(){
      this.level = 1;
      this.iconNumber = initIconNumber;
      this.initData();
    },
    //点击卡片
    slectedCard(item,index,event){
      //如果选择超出了7个，就输了
      if(this.slectedCardList.length === 7){
        alert("你输了！");
        return false;
      }
      //检测元素是否被覆盖
      if (!this.hasOverLayer(event.srcElement)){
        //当前选择的卡片
        this.currentSlectedCard=item;
        //删除allCards里面
        this.allCards.splice(index,1);
        //记录选择的卡片，用于撤回
        this.historySlectedCard.push(item);
        //然后选择
        this.slectedCardList.push(item);
        //选择的卡片排序
        this.slectedCardList.sort((a,b)=>{
          return a.order - b.order;
        })
        //选择的卡片中有3个同样的卡片的话，消除
        setTimeout(()=>{
          this.remove3Card()
        },200)
      }
    },
    //选择的卡片中有3个同样的卡片的话，消除
    remove3Card(){
      let currentNum=0;
      this.slectedCardList.forEach(item=>{
        if(item.icon===this.currentSlectedCard.icon){
          currentNum++;
        }
      })
      if (currentNum >= 3){
        this.slectedCardList = this.slectedCardList.filter(item=>{
          return item.icon !== this.currentSlectedCard.icon;
        })
        //消除记录里面的
        this.historySlectedCard = this.historySlectedCard.filter(item=>{
          return item.icon !== this.currentSlectedCard.icon;
        })
      }
      //赢了
      if(this.allCards.length ===0){
        alert("恭喜你，你赢了！");
        this.level++;
        switch (this.level){
          case 2:this.iconNumber = 60 ; break;//20组
          case 3:this.iconNumber = 99 ; break;//33组
          case 4:this.iconNumber = 300 ; break;//100组
          case 5:this.iconNumber = 900 ; break;//300组
          default : this.iconNumber = 1500; break;//500组
        }
        this.initData()
      }
    },
    //检测元素是否被覆盖
    hasOverLayer(element){
      //获取document
      let document = element.ownerDocument;
      //获取目标的矩形信息
      let rect = element.getBoundingClientRect();
      let x = rect.x;
      let y = rect.y;
      let width = rect.width;
      let height = rect.height;
      x |= 0;
      y |= 0;
      width |= 0;
      height |= 0;
      //四顶点取样
      let elements=[
          document.elementFromPoint(x+1,y+1),
          document.elementFromPoint(x+width-1,y+1),
          document.elementFromPoint(x+1,y+height-1),
          document.elementFromPoint(x+width-1,y+height-1),
      ];
      console.log(elements)
      //判断非本身并且非子孙元素
      return elements.filter(el => el !=null).some(el=> el !==element && !element.contains(el))
    },
    //生成数据
    initData(){
      this.allCards = [];
      //卡片定位数组
      this.cardPositionList = [];
      //选择的卡片
      this.slectedCardList = [];
      //当前选择的卡片
      this.currentSlectedCard= {};
      //第一层
      let index=0;
      let left=0;
      let top=0;
      for (let i= 0; i < 7;i++){//列
        for (let j= 0; j < 7;j++){//行
          this.cardPositionList.push({id:index++,icon:1,left:left+'px',top:top+'px'})
          left+=50;
        }
        left=0;
        top+=50;
      }

      //第二层
      left=25;
      top=25;
      for (let i= 0; i < 6;i++){//列
        for (let j= 0; j < 6;j++){//行
          this.cardPositionList.push({icon:2,left:left+'px',top:top+'px'})
          left+=50;
        }
        left=25;
        top+=50;
      }
      //生成随机图标
      this.generateRandomIcon();
    },
    //生成随机图标
    generateRandomIcon(){
      let random = 0;
      for(let i=0; i < this.iconNumber; i++){
        //每三次循环，一次生成随机数
        if (i % 3 === 0){
          random = Math.floor(Math.random()*10);
        }
        this.allCards.push({
          id:i,
          icon:this.iconList[random].icon,
          order:this.iconList[random].order,
          bgColor:this.iconList[random].bg,
        })
        //实现allCards随机排序
        this.allCards.sort(()=>{
          return Math.random() > 0.5 ? -1 : 1;
        })
	    }//end 随机排序
      //给卡片重新定位
      //随机位置
      random = 0;
      this.allCards.forEach(item=>{
        random = Math.floor(Math.random() * (this.cardPositionList.length-1));
        item['left'] = this.cardPositionList[random].left;
        item['top'] = this.cardPositionList[random].top;
      })
    }
  }
}
</script>

<style lang="scss">
:root{
  --bg:rgb(195,255,139);
}
body{
  background-color: var(--bg);
}
.box{
  width:350px;
  height:400px;
  margin: 30px auto 20px;
  position: relative;
  .card{
    position: absolute;
  }
}
.bottom{
  height: 60px;
  width: 350px;
  background-color: rgb(150,90,27);
  margin: auto;
  border-radius: 6px;
  padding: 0 5px;
  div{
    margin-top: 5px;
    display: inline-block;
  }
}
.card{
  width: 48px;
  height: 48px;
  border: 1px solid green;
  line-height: 50px;
  text-align: center;
  background-color: white;
  color: #fff;
  font-size: 36px;
  border-radius: 4px;
  box-shadow: 0 0 10px 0 #545454;
  img{
    width: 35px;
    height: 35px;
  }
  .bot{
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 5px;
    background-color: #90ee90;
    border-bottom-left-radius: 3px;
    border-bottom-right-radius: 3px;
    border-bottom: 2px solid green;
  }
}
.btn{
  display: flex;
  justify-content: center;
  margin-top: 50px;
}
.level{
  height: 50px;
  line-height: 50px;
  text-align: center;
  font-family: cursive;
  font-size: 30px;
  font-weight: bold;
}
.author{
  width: 100%;
  text-align: center;
  font-size: 14px;
}
.version{
  margin-top: 50px;
  color: #999;
}
</style>
